akw27@boulderdash.cl.cam.ac.uk
+kaf24@labyrinth.cl.cam.ac.uk
kaf24@plym.cl.cam.ac.uk
kaf24@striker.cl.cam.ac.uk
smh22@boulderdash.cl.cam.ac.uk
static inline void __save_init_fpu( struct task_struct *tsk )
{
- if ( cpu_has_fxsr ) {
- asm volatile( "fxsave %0 ; fnclex"
- : "=m" (tsk->thread.i387.fxsave) );
- } else {
- asm volatile( "fnsave %0 ; fwait"
- : "=m" (tsk->thread.i387.fsave) );
- }
- tsk->flags &= ~PF_USEDFPU;
+ if ( cpu_has_fxsr ) {
+ asm volatile( "fxsave %0 ; fnclex"
+ : "=m" (tsk->thread.i387.fxsave) );
+ } else {
+ asm volatile( "fnsave %0 ; fwait"
+ : "=m" (tsk->thread.i387.fsave) );
+ }
+ tsk->flags &= ~PF_USEDFPU;
}
void save_init_fpu( struct task_struct *tsk )
{
- __save_init_fpu(tsk);
- stts();
+ /*
+ * The guest OS may have set the 'virtual STTS' flag.
+ * This causes us to set the real flag, so we'll need
+ * to temporarily clear it while saving f-p state.
+ */
+ if ( tsk->flags & PF_GUEST_STTS ) clts();
+ __save_init_fpu(tsk);
+ stts();
}
void restore_fpu( struct task_struct *tsk )
/* No nested task. */
__asm__("pushfl ; andl $0xffffbfff,(%esp) ; popfl");
+ /* Ensure FPU gets initialised for each domain. */
+ stts();
+
/* Set up and load the per-CPU TSS and LDT. */
t->ss0 = __HYPERVISOR_DS;
t->esp0 = current->thread.esp0;
asmlinkage void math_state_restore(struct pt_regs *regs, long error_code)
{
- __asm__ __volatile__("clts");
+ /* Prevent recursion. */
+ clts();
if ( !(current->flags & PF_USEDFPU) )
{